import 'package:dio/dio.dart';
import 'package:furaha_mkopo/net/fm_http_model.dart';
import 'fm_http_exception.dart';
import 'fm_http_interceptor_error.dart';
import 'fm_http_request.dart';
import 'fm_http_response.dart';

class FMHttpManager {

  static FMHttpManager? _instance;

  static FMHttpManager getInstance() {
    _instance ??= FMHttpManager._();
    return _instance!;
  }

  static late Dio _dio;

  FMHttpManager._() {
    init();
  }

  void init() {
    final BaseOptions options = BaseOptions(
      connectTimeout: 50000,
      receiveTimeout:50000,
      sendTimeout:50000,
    );
    // 实例化 Dio
    _dio = Dio(options);

    _dio.interceptors.add(FMHttpInterceptorError());
  }

  Future<FMHttpResponse<K>> send<T, K>(
      FMHttpRequest request, T? decodeType, CancelToken? cancelToken) async {

    dynamic data = "";
    var params = request.requestParams();
    Options options =
    Options(method: request.method(), extra: {}, headers: {});

    FMHttpMethodType methodType = request.methodType();
    if (methodType == FMHttpMethodType.upload) {
      FormData formData = FormData.fromMap(params);
      if(request.uploadData() != null){
        formData.files.add(MapEntry(request.requestUploadKey(),
            MultipartFile.fromBytes(request.uploadData()!, filename: 'image.png')
        ));
      }
      data = formData;
    }
    if (methodType == FMHttpMethodType.post) {
      options.contentType = "application/x-www-form-urlencoded";
      options.method = "POST";
      data = params;
    }

    try {
      Response response = await _dio.request(
        request.url(),
        data: data,
        queryParameters: params,
        options: options,
      );

      var code = response.data['cheers'];
      var msg = response.data['hurrah'];

      if (code == 0) {
        var decode = request
            .decode()
            .decode<T, K>(response: response, decodeType: decodeType);
        return FMHttpResponse(code: 0, message: null, data: decode);
      }else {
        return FMHttpResponse(code: code, message: msg, data:null);
      }
    } on DioError catch (e) {
      return FMHttpResponse(code:e.response?.statusCode ?? -1, message: e.message, data: null);
    }  on FMHttpException catch (e) {
      return FMHttpResponse(code: e.code, message: e.message, data: null);
    } on TypeError catch (e) {
      return FMHttpResponse(code: -1, message: e.toString(), data: null);
    }
  }


  void dynamicServerUrl(Function(bool isSuccess,List<String> urls,String? message) request){
    _dio
        .get(
        "https://tza01-dc.oss-ap-southeast-1.aliyuncs.com/furaha-mkopo-ios/fur.json")
        .then((value) {
          if(value.statusCode != 200){
            request(false,[],value.statusMessage);
            return;
          }
          if(value.data == null && value.data is! List){
            request(false,[],value.statusMessage);
            return;
          }
          List serverUrls = value.data;
          List<String>? urls = serverUrls.map((e) => e["ff"]?.toString()??"").toList();
          if(urls.isEmpty){
            request(false,[],value.statusMessage);
            return;
          }
          request(true,urls,value.statusMessage);
    });
  }
}